package biblioteca;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Biblioteca {
	
	private final double EPS = 1e-8;
	
	List<Item> itens;
	List<Usuario> usuarios;
	
	public Biblioteca () {
		itens = new ArrayList<Item>();
		usuarios = new ArrayList<Usuario>();
	}
	
	public Biblioteca(List<Item> itens, List<Usuario> usuarios) {
		this.itens = itens;
		this.usuarios = usuarios;
	}
	
	public void adicionaItem(Item item) {
		itens.add(item);
	}
	
	public void adicionaUsuario(Usuario usuario) {
		usuarios.add(usuario);
	}
	
	public List<Livro> listaDeLivros() {
		List<Livro> lista = new ArrayList<Livro>();
		
		for(Item item : itens) {
			if(item instanceof Livro)
				lista.add((Livro)item);
		}
		
		return lista;
	}
	
	public List<String> listaDeGeneros() {
		List<String> lista = new ArrayList<String>();
		
		for(Livro livro : listaDeLivros()) {
			if(!lista.contains(livro.getGenero()))
				lista.add(livro.getGenero());
		}
		
		return lista;
	}
	
	public List<String> listaDeAutores() {
		List<String> lista = new ArrayList<String>();
		
		for(Livro livro : listaDeLivros()) {
			if(!lista.contains(livro.getAutor()))
				lista.add(livro.getAutor());
		}
		
		return lista;
	}
	
	public List<Item> pesquisaItens(String string) {
		List<Item> lista = new ArrayList<Item>();
		
		for(Item item : itens)
			if(item.toString().contains(string))
				lista.add(item);
		
		return lista;
	}
	
	public List<Livro> pesquisaLivros(String string) {
		List<Livro> lista = new ArrayList<Livro>();
		
		for(Livro livro : listaDeLivros()) {
			if(livro.toString().contains(string))
				lista.add(livro);
		}
		
		return lista;
	}
	
	public List<Usuario> pesquisaUsuarios(String string) {
		List<Usuario> lista = new ArrayList<Usuario>();
		
		for(Usuario usuario : usuarios)
			if(usuario.toString().contains(string))
				lista.add(usuario);
		
		return lista;
	}
	
	public List<Livro> pesquisaLivrosPorTitulo(String titulo) {
		List<Livro> lista = new ArrayList<Livro>();
		
		for(Livro livro : listaDeLivros())
			if(livro.getTitulo().contains(titulo))
				lista.add(livro);
		
		return lista;
	}
	
	public List<Livro> pesquisaLivrosPorAutor(String autor) {
		List<Livro> lista = new ArrayList<Livro>();
		
		for(Livro livro : listaDeLivros())
			if(livro.getAutor().contains(autor))
				lista.add(livro);
		
		return lista;
	}
	
	public List<Livro> pesquisaLivrosPorGenero(String genero) {
		List<Livro> lista = new ArrayList<Livro>();
		
		for(Livro livro : listaDeLivros())
			if(livro.getGenero().contains(genero))
				lista.add(livro);
		
		return lista;
	}
	
	public List<Livro> pesquisaLivrosPorUsuario(Usuario usuario) {
		List<Livro> lista = new ArrayList<Livro>();
		
		for(Livro livro : listaDeLivros())
			if(livro.getUsuarioAtual().equals(usuario))
				lista.add(livro);
		
		return lista;
	}
	
	public List<Usuario> usuariosMaisAtivos() {
		List<Usuario> lista = new ArrayList<Usuario>();
		
		lista.addAll(usuarios);
		Collections.sort(lista);
		
		return lista;
	}
	
	public List<Item> itensMaisVotados() {
		List<Item> lista = new ArrayList<Item>();
		
		lista.addAll(itens);
		Collections.sort(lista, new ComparadorMaisVotado());
		
		return lista;
	}
	
	public List<Item> itensMaisUsados() {
		List<Item> lista = new ArrayList<Item>();
		
		lista.addAll(itens);
		Collections.sort(lista, new ComparadorMaisUsado());
		
		return lista;
	}
	
	public List<Livro> livrosMaisVotados() {
		List<Livro> lista = listaDeLivros();
		
		Collections.sort(lista, new ComparadorMaisVotado());
		
		return lista;
	}
	
	public List<Livro> livrosMaisLidos() {
		List<Livro> lista = listaDeLivros();
		
		Collections.sort(lista, new ComparadorMaisUsado());
		
		return lista;
	}
	
	public List<String> generosMaisVotados() {
		List<String> lista = listaDeGeneros();
		
		for(int i=0; i<lista.size()-1; i++)
			for(int j=0; j<lista.size()-1-i; j++)
				if(notaGenero(lista.get(j+1)) - notaGenero(lista.get(j)) > EPS)
					Collections.swap(lista, j, j+1);
		
		return lista;
	}
	
	public List<String> generosMaisLidos() {
		List<String> lista = listaDeGeneros();
		
		for(int i=0; i<lista.size()-1; i++)
			for(int j=0; j<lista.size()-1-i; j++)
				if(leiturasGenero(lista.get(j+1)) - leiturasGenero(lista.get(j)) > 0)
					Collections.swap(lista, j, j+1);
		
		return lista;
	}
	
	public List<String> autoresMaisVotados() {
		List<String> lista = listaDeAutores();
		
		for(int i=0; i<lista.size()-1; i++)
			for(int j=0; j<lista.size()-1-i; j++)
				if(notaAutor(lista.get(j+1)) - notaAutor(lista.get(j)) > EPS)
					Collections.swap(lista, j, j+1);
		
		return lista;
	}
	
	public List<String> autoresMaisLidos() {
		List<String> lista = listaDeAutores();
		
		for(int i=0; i<lista.size()-1; i++)
			for(int j=0; j<lista.size()-1-i; j++)
				if(leiturasAutor(lista.get(j+1)) - leiturasAutor(lista.get(j)) > 0)
					Collections.swap(lista, j, j+1);
		
		return lista;
	}
	
	public double notaGenero(String genero) {
		return mediaDeNotas(pesquisaLivrosPorGenero(genero));
	}
	
	public double leiturasGenero(String genero) {
		return numeroDeLeituras(pesquisaLivrosPorGenero(genero));
	}
	
	public double notaAutor(String autor) {
		return mediaDeNotas(pesquisaLivrosPorAutor(autor));
	}
	
	public double leiturasAutor(String autor) {
		return numeroDeLeituras(pesquisaLivrosPorAutor(autor));
	}
	
	public double mediaDeNotas(List<Livro> livros) {
		double soma = 0.0;
		
		for(Livro livro : livros)
			soma += livro.calculaMedia();
		
		return ( soma / livros.size() );
	}
	
	public int numeroDeLeituras(List<Livro> livros) {
		int leituras = 0;
		
		for(Livro livro : livros)
			leituras += livro.getNumeroDeUsos();
		
		return leituras;
	}
	//pra apagar
	public List<Item> getLivrosLidos(Usuario usuario){
		List<Item> livrosLidos = new ArrayList<Item>();  
		for(Item l: itens){
			if(((Livro) l).getLido(usuario)!=null){
				livrosLidos.add(l);
			}		
		}
		return livrosLidos;
	}
	
	public List<Item> getLivrosPorStatus(List<Item> itens,Status status){
		List<Item> livros = new ArrayList<Item>();  
		for(Item item: itens){
			if(((Livro) item).getStatus()==status){
				livros.add(item);
			}		
		}
		return livros;
	}
}
